﻿#region

using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using BusinessObjects;

#endregion

namespace DataAccessLayer
{
    public static class UserDAL
    {
        private static readonly string ConnectionString =
            ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;

        public static bool IsUsernameTaken(string uname)
        {
            using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString))
            {
                con.Open();
                var cmd = new SqlCommand("spIsUsernameTaken", con) {CommandType = CommandType.StoredProcedure};
                var unameParameter = new SqlParameter("@Username", uname);
                var returnCodeParameter = new SqlParameter("@ReturnCode", SqlDbType.Bit)
                {
                    Direction = ParameterDirection.Output
                };
                cmd.Parameters.Add(unameParameter);
                cmd.Parameters.Add(returnCodeParameter);
                cmd.ExecuteNonQuery();
                return Convert.ToBoolean(returnCodeParameter.Value);
            }
        }

        public static bool LoginUser(User user)
        {
            using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString))
            {
                con.Open();
                var cmd = new SqlCommand("spIsValidLogin", con) {CommandType = CommandType.StoredProcedure};
                var unameParameter = new SqlParameter("@Username", user.Username);
                var passParameter = new SqlParameter("@Password", user.Password);
                cmd.Parameters.Add(unameParameter);
                cmd.Parameters.Add(passParameter);
                return Convert.ToBoolean(cmd.ExecuteScalar());
            }
        }

        public static bool IsBannedUser(User user)
        {
            using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString))
            {
                con.Open();
                var cmd = new SqlCommand("spIsBannedUser", con) {CommandType = CommandType.StoredProcedure};
                var unameParameter = new SqlParameter("@Username", user.Username);
                cmd.Parameters.Add(unameParameter);
                return Convert.ToBoolean(cmd.ExecuteScalar());
            }
        }

        public static void UpdatePassword(User user)
        {
            using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString))
            {
                con.Open();
                var cmd = new SqlCommand("spUpdatePassword", con) {CommandType = CommandType.StoredProcedure};
                var unameParameter = new SqlParameter("@Username", user.Username);
                var passwordParameter = new SqlParameter("@Password", user.Password);
                cmd.Parameters.Add(unameParameter);
                cmd.Parameters.Add(passwordParameter);
                cmd.ExecuteNonQuery();
            }
        }

        /// <summary>
        ///     Remove a user
        /// </summary>
        /// <param name="username">Represent's the user's username</param>
        public static void RemoveUser(string username)
        {
            using (var connection = new SqlConnection(ConnectionString))
            {
                var command = new SqlCommand("spRemoveUser", connection)
                {
                    CommandType = CommandType.StoredProcedure
                };

                command.Parameters.AddWithValue("@Username", username);

                connection.Open();
                command.ExecuteNonQuery();
            }
        }

        /// <summary>
        ///     Change user's status (Ban or unban user)
        /// </summary>
        /// <param name="user">Represent's the user</param>
        public static void ChangeUserStatus(User user)
        {
            using (var connection = new SqlConnection(ConnectionString))
            {
                var command = new SqlCommand("spChangeUserStatus", connection)
                {
                    CommandType = CommandType.StoredProcedure
                };

                command.Parameters.AddWithValue("@Username", user.Username);
                command.Parameters.AddWithValue("@Status", user.Status);

                connection.Open();
                command.ExecuteNonQuery();
            }
        }

        /// <summary>
        ///     Get user by username
        /// </summary>
        /// <param name="username">Represent's the user's username</param>
        /// <returns>User</returns>
        public static User GetUserByUsername(string username)
        {
            using (var connection = new SqlConnection(ConnectionString))
            {
                var command = new SqlCommand("spGetUserByUsername", connection)
                {
                    CommandType = CommandType.StoredProcedure
                };

                command.Parameters.AddWithValue("@Username", username);

                connection.Open();
                using (var reader = command.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        var user = new User
                        {
                            Username = reader["Username"].ToString(),
                            Password = reader["Password"].ToString(),
                            Status = Convert.ToBoolean(reader["Status"]),
                            Type = reader["Type"].ToString()
                        };

                        return user;
                    }
                }
            }
            return null;
        }

        /// <summary>
        ///     Request reset password
        /// </summary>
        /// <param name="username">Represent's the user's username</param>
        /// <returns>Unique id</returns>
        public static Guid RequestResetPassword(string username)
        {
            using (SqlConnection connection = new SqlConnection(ConnectionString))
            {
                SqlCommand command = new SqlCommand("spRequestPassword", connection)
                {
                    CommandType = CommandType.StoredProcedure
                };

                command.Parameters.AddWithValue("@Username", username);

                connection.Open();
                return (Guid) command.ExecuteScalar();
            }
        }

        /// <summary>
        ///     Validate reset link
        /// </summary>
        /// <param name="uniqueId">Represent's the unique id</param>
        /// <returns>Valid or not</returns>
        public static bool IsResetLinkValid(Guid uniqueId)
        {
            using (SqlConnection connection = new SqlConnection(ConnectionString))
            {
                SqlCommand command = new SqlCommand("spIsRestLinkValid", connection)
                {
                    CommandType = CommandType.StoredProcedure
                };

                command.Parameters.AddWithValue("@UniqueId", uniqueId);

                connection.Open();
                return Convert.ToBoolean(command.ExecuteScalar());
            }
        }

        /// <summary>
        ///     Change password
        /// </summary>
        /// <param name="uniqueId">Represent's the unique id</param>
        /// <param name="password">Represent's the encrypted password</param>
        public static void UpdatePassword(Guid uniqueId, string password)
        {
            using (SqlConnection connection = new SqlConnection(ConnectionString))
            {
                SqlCommand command = new SqlCommand("spChangePasswordByUniqueId", connection)
                {
                    CommandType = CommandType.StoredProcedure
                };

                command.Parameters.AddWithValue("@UniqueId", uniqueId);
                command.Parameters.AddWithValue("@Password", password);

                connection.Open();
                command.ExecuteNonQuery();
            }
        }

        /// <summary>
        ///     Get reset password requestor's username
        /// </summary>
        /// <param name="uniqueId">Represent's the unique id</param>
        /// <returns>User's username</returns>
        public static string GetResetPasswordRequestorUsername(Guid uniqueId)
        {
            using (SqlConnection connection = new SqlConnection(ConnectionString))
            {
                SqlCommand command = new SqlCommand("spGetPasswordRequestorUsernameByUniqueId", connection)
                {
                    CommandType = CommandType.StoredProcedure
                };

                command.Parameters.AddWithValue("@UniqueId", uniqueId);

                connection.Open();
                object username = command.ExecuteScalar();

                return username == null ? null : username.ToString();
            }
        }
    }
}